import Vue from 'vue';
import { Subject, Subscription } from 'rxjs';
import { Component, Prop } from 'vue-property-decorator';
import { AppVisualCtrlItem } from '../app-visual-ctrl-item/app-visual-ctrl-item';
import { CtrlEvent, ISheetParam } from '../../interface';
import { SheetUtil, Util } from '../../utils';
import AppVisualFormService from './app-visual-form-service';
import './app-visual-form.less';

/**
 * 自定义绘制虚拟表单控件
 *
 * @export
 * @class AppVisualForm
 * @extends {Vue}
 */
@Component({
    components: {
        AppVisualCtrlItem
    }
})
export class AppVisualForm extends Vue {

    /**
     * 控件位置
     *
     * @type {*}
     * @memberof AppVisualForm
     */
    @Prop() position!: any;

    /**
     * 默认配置参数
     *
     * @type {*}
     * @memberof AppVisualForm
     */
    @Prop() sheetConfig!: any;

    /**
     * 表单项
     *
     * @type {*}
     * @memberof AppVisualForm
     */
    @Prop() items!: any;

    /**
     * 控件ID
     *
     * @type {*}
     * @memberof AppVisualForm
     */
    @Prop() id!: string;

    /**
     * 是否可设计控件
     *
     * @type {*}
     * @memberof AppVisualForm
     */
    @Prop() enableDesgin?: boolean;

    /**
     * @description sheet状态通知对象
     * @type {Subject<ISheetParam>}
     * @memberof AppVisualForm
     */
    @Prop() public sheetState !: Subject<ISheetParam>;

    /**
     * @description 是否激活
     * @type {boolean}
     * @memberof AppVisualForm
     */
    public isActiveCtrl: boolean = false;

    /**
     * sheet状态事件
     *
     * @public
     * @type {(Subscription | undefined)}
     * @memberof AppVisualForm
     */
    public sheetStateEvent: Subscription | undefined;

    /**
     * @description 真实组件引用
     * @private
     * @type {*}
     * @memberof AppVisualForm
     */
    private realCompRef: any;

    /**
     * @description 数据服务
     * @private
     * @type {AppVisualFormService}
     * @memberof AppVisualForm
     */
    private service!: AppVisualFormService;

    /**
     * @description 部件初始化
     * @memberof AppVisualForm
     */
    public created() {
        if (this.sheetState) {
            this.sheetStateEvent = this.sheetState.subscribe(({ tag, action, data }: { tag: string, action: string, data: any }) => {
                if (!Object.is(tag, this.id)) {
                    return;
                }
                if (Object.is(action, 'CELLMOUSEDOWN')) {
                    this.handleCellMouseDown(data);
                }
                if (Object.is(action, 'UPDATE')) {
                    this.handleSheetUpdate(data);
                }
                if (Object.is(action, 'RENDERCONTEXTMENU')) {
                    this.handleRenderContextMenu(data);
                }
                if (Object.is(action, 'CLEAR') && this.service) {
                    this.service.handClearAll();
                }
            })
        }
    }

    /**
     * @description 挂载完成
     * @memberof AppVisualForm
     */
    public mounted() {
        const refNode = (this.$slots.default as any[])[0];
        refNode.componentInstance.$on('ctrl-event', (args: any) => {
            const { controlname, action, data } = args;
            console.log(controlname, action, data)
            if (Object.is(action, 'controlIsMounted')) {
                this.realCompRef = refNode.componentInstance.$refs.ctrl;
                const controlInstance = this.realCompRef.controlInstance;
                this.service = new AppVisualFormService({ controlInstance, sheetConfig: this.sheetConfig, position: this.position });
                if (this.enableDesgin) {
                    this.initVisualCtrl();
                }
            }
            if (Object.is(action, 'load')) {
                this.initVisualCtrl(data);
            }
        })
    }

    /**
     *  @description 组件销毁
     * 
     * @memberof AppSheetDesign
     */
    public destory() {
        if (this.sheetStateEvent) {
            this.sheetStateEvent.unsubscribe();
        }
    }

    /**
     * @description 初始化虚拟表单
     * @param {*} data 表单数据
     * @memberof AppVisualForm
     */
    public initVisualCtrl(data: any = {}) {
        this.service.initVisualCtrl(data);
        this.$emit(CtrlEvent.INITD, this.getEmitParam({ position: this.position, items: this.items, sheetConfig: this.service.sheetConfig }));
    }

    /**
     * @description 处理控件项值变化
     * @param {*} data
     * @memberof AppVisualForm
     */
    public handleCtrlItemValueChange(data: any) {
        const { name, value } = data;
        // 设置当前单元格值
        if (this.service.positionMap.has(name)) {
            const element = this.service.positionMap.get(name);
            (window as any).luckysheet.setCellValue(element.row, element.startCol + 1, value);
        }
        // 设置虚拟控件数据
        this.service.visualCtrlData[name] = value;
        // 设置原生控件数据
        if (this.realCompRef.onFormItemValueChange instanceof Function) {
            this.realCompRef.onFormItemValueChange(data);
        }
    }

    /**
     * @description 挂载Item
     * @memberof AppVisualForm
     */
    public mountedFormItem(key: string, position: any) {
        let _this = this;
        const vm = new Vue({
            render(h) {
                return h(AppVisualCtrlItem,
                    {
                        props: {
                            realCompRef: _this.realCompRef?.$refs[key]?.$refs['editor']?.$refs['editor'],
                            detailInstance: _this.service.formItemMap.get(key),
                            position: position,
                            id: key,
                            value: _this.service.visualCtrlData[key],
                            codeListService: _this.realCompRef.codeListService,
                            context: _this.realCompRef.context,
                            viewparam: _this.realCompRef.viewparams,
                        },
                        on: {
                            change: (data: any) => {
                                _this.handleCtrlItemValueChange(data);
                            }
                        }
                    });
            }
        }).$mount();
        SheetUtil.getElement('#luckysheet-ctrl-showBoxs .ctrl-list').append(vm.$el);
    }

    /**
     * @description 控件单元格点击
     * @param {*} data
     * @memberof AppVisualForm
     */
    public handleCellMouseDown(data: any) {
        const { cell, position, sheetFile } = data;
        // 清空所有编辑项
        SheetUtil.getElement('.app-visual-ctrl-item').remove();
        if (cell && cell.codeName) {
            const tempPosition = {
                left: position.start_c,
                top: position.start_r,
                width: position.end_c - position.start_c - 2,
                height: position.end_r - position.start_r - 2
            };
            // 存储位置信息
            const storePosition = Util.deepCopy(this.service.positionMap.get(cell.codeName));
            Object.assign(storePosition, { position: tempPosition });
            this.service.positionMap.set(cell.codeName, storePosition);
            // 挂载表单项
            this.mountedFormItem(cell.codeName, tempPosition);
        } else {
            this.isActiveCtrl = this.service.checkSelectedCtrl(position);
            if (this.isActiveCtrl) {
                this.$emit(CtrlEvent.ACTIVATED, this.getEmitParam({ position: this.position, items: this.items, sheetConfig: this.service.sheetConfig }));
            } else {
                this.$emit(CtrlEvent.DEACTIVATED, this.getEmitParam({ position: this.position, items: this.items, sheetConfig: this.service.sheetConfig }));
            }
        }
    }

    /**
     * @description 控件变化
     * @param {*} operate
     * @memberof AppVisualForm
     */
    public handleSheetUpdate(operate: any) {
        const { type, curConfig, curconfig, curData, curdata } = operate;
        // 清空绘制编辑器
        SheetUtil.getElement('.app-visual-ctrl-item').remove();
        // 抛值修改
        let emitData = curData ? (window as any).luckysheet.transToCellData(curData) : curdata ? (window as any).luckysheet.transToCellData(curdata) : {};
        let emitConf = curConfig ? curConfig : curconfig ? curconfig : {};
        this.$emit(CtrlEvent.CONFCHANGE, this.getEmitParam({ position: this.position, items: this.items, sheetConfig: { config: emitConf, data: emitData } }));
    }

    /**
     * @description 处理渲染上下文菜单
     * @param {*} { cell, position, sheetFile, event }
     * @memberof AppVisualForm
     */
    public handleRenderContextMenu({ cell, position, sheetFile, event }: any) {
        console.log("渲染上下文菜单", cell, position, sheetFile, event);
    }

    /**
     * @description 获取抛出参数
     * @param {*} data
     * @return {*} 
     * @memberof AppVisualForm
     */
    public getEmitParam(data: any) {
        return {
            id: this.id,
            type: 'FORM',
            ...data
        }
    }

    /**
     * @description 绘制虚拟表单控件
     * @return {*} 
     * @memberof AppVisualForm
     */
    public render() {
        return (<div class="app-visual-form">
            <div class="main-content">
                {this.$slots.default}
            </div>
        </div>)
    }

}